<style lang="less">
    @import "roleManage.less";
</style>
<template>
    <div class="search">
        <Row>
            <Col>
                <Card>
                    <Row class="operation">
                        <Button @click="addRole" type="primary" icon="md-add">添加角色</Button>
                        <Button @click="delAll" icon="md-trash">批量删除</Button>
                        <Button @click="init" icon="md-refresh">刷新</Button>
                        <circleLoading v-if="operationLoading"/>
                    </Row>
                    <Row>
                        <Alert show-icon>
                            已选择 <span class="select-count">{{selectCount}}</span> 项
                            <a class="select-clear" @click="clearSelectAll">清空</a>
                        </Alert>
                    </Row>
                    <Row>
                        <Table :loading="loading" border :columns="columns" :data="data" ref="table" sortable="custom"
                               @on-sort-change="changeSort" @on-selection-change="changeSelect">
                            <template slot-scope="{ row }" slot="action">
                                <div>
                                    <Button type="warning" size="small" style="margin-right: 5px"
                                            @click="editPerm(row)">菜单权限
                                    </Button>
                                    <Button type="primary" size="small" style="margin-right: 5px" @click="editDep(row)">
                                        数据权限
                                    </Button>
                                    <Button size="small" style="margin-right: 5px" @click="edit(row)">编辑</Button>
                                    <Button type="error" size="small" @click="remove(row)">删除</Button>
                                </div>
                            </template>
                        </Table>
                    </Row>
                    <Row type="flex" justify="end" class="page">
                        <Page :current="pageNumber" :total="total" :page-size="pageSize" @on-change="changePage"
                              @on-page-size-change="changePageSize" :page-size-opts="[10,20,50]" size="small" show-total
                              show-elevator show-sizer></Page>
                    </Row>
                </Card>
            </Col>
        </Row>
        <!-- 编辑 -->
        <Modal :title="modalTitle" v-model="roleModalVisible" :mask-closable='false' :width="500">
            <Form ref="roleForm" :model="roleForm" :label-width="80" :rules="roleFormValidate">
                <FormItem label="角色编码" prop="roleCode">
                    <Input v-model="roleForm.roleCode" placeholder="按照Spring Security约定建议以‘ROLE_’开头"/>
                </FormItem>
                <FormItem label="角色名称" prop="roleName">
                    <Input v-model="roleForm.roleName"/>
                </FormItem>
            </Form>
            <Transfer
                v-if="transInit"
                :data="transSearchData"
                :target-keys="transData"
                :titles="['无该角色用户','有该角色用户']"
                :operations="['移除','添加']"
                :filterable="true"
                filter-placeholder="输入用户名"
                @on-change="userTrans">
            </Transfer>
            <div slot="footer">
                <Button type="text" @click="cancelRole">取消</Button>
                <Button type="primary" :loading="submitLoading" @click="submitRole">提交</Button>
            </div>
        </Modal>
        <!-- 菜单权限 -->
        <Modal :title="modalTitle" v-model="permModalVisible" :mask-closable='false' :width="500"
               :styles="{top: '30px'}" class="permModal">
            <Tree ref="tree" :data="permData" multiple></Tree>
            <Spin size="large" v-if="treeLoading"></Spin>
            <div slot="footer">
                <Button type="text" @click="cancelPermEdit">取消</Button>
                <Button @click="selectTreeAll">全选/反选</Button>
                <Button type="primary" :loading="submitPermLoading" @click="submitPermEdit">提交</Button>
            </div>
        </Modal>
        <!-- 数据权限 -->
        <Modal :title="modalTitle" v-model="depModalVisible" :mask-closable='false' :width="500" :styles="{top: '30px'}"
               class="depModal">
            <Form :label-width="65">
                <FormItem label="数据范围">
                    <Select v-model="dataType">
                        <Option :value='0'>全部数据权限</Option>
                        <Option :value='1'>本级及下级权限</Option>
                        <Option :value='2'>自定义数据权限</Option>
                    </Select>
                </FormItem>
            </Form>
            <Alert show-icon>
                默认可查看全部数据，自定义数据范围请点击选择下方数据
            </Alert>
            <div v-if="dataType!=0" style="margin-top:15px">
                <Tree ref="depTree" :data="depData" :load-data="loadData" @on-toggle-expand="expandCheckDep" multiple
                      style="margin-top:15px"></Tree>
                <Spin size="large" v-if="depTreeLoading"></Spin>
            </div>
            <div slot="footer">
                <Button type="text" @click="depModalVisible=false">取消</Button>
                <Button type="primary" :loading="submitDepLoading" @click="submitDepEdit">提交</Button>
            </div>
        </Modal>
    </div>
</template>

<script>
    import {
        getRoleList,
        addRole,
        editRole,
        deleteRole,
        editRolePerm,
        editRoleDep,
        userTransferList
    } from "@/projects/basic/api/admin/role";

    import {
        getAllPermissionList
    } from '@/projects/basic/api/admin/menu';

    import {
        initDepartment,
        loadDepartment
    } from "@/projects/basic/api/admin/department";

    import util from "@/libs/util.js";
    import circleLoading from "_c/circle-loading/circle-loading.vue";

    export default {
        name: "role-manage",
        components: {
            circleLoading
        },
        data() {
            return {
                loading: true,
                treeLoading: true,
                depTreeLoading: true,
                operationLoading: false,
                submitPermLoading: false,
                submitDepLoading: false,
                transInit:false,
                transSearchData:[],
                transData:[],
                searchKey: "",
                sortColumn: "createTime",
                sortType: "desc",
                modalType: 0,
                roleModalVisible: false,
                permModalVisible: false,
                depModalVisible: false,
                modalTitle: "",
                roleForm: {
                    roleCode:"",
                    roleName: ""
                },
                roleFormValidate: {
                    roleCode: [{required: true, message: "角色名称不能为空", trigger: "blur"}],
                    roleName: [{required: true, message: "角色名称不能为空", trigger: "blur"}],
                },
                submitLoading: false,
                selectList: [],
                selectCount: 0,
                columns: [
                    {
                        type: "selection",
                        maxWidth: 60,
                        align: "center",
                        fixed: 'left'
                    },
                    {
                        type: "index",
                        maxWidth: 60,
                        align: "center"
                        ,
                        fixed: 'left'
                    },
                    {
                        title: "角色编码",
                        key: "roleCode",
                        fixed: 'left'
                    },
                    {
                        title: "角色名",
                        key: "roleName",
                    },
                    {
                        title: "创建时间",
                        key: "createTime",
                    },
                    {
                        title: "更新时间",
                        key: "updateTime",
                    },
                    {
                        title: "操作",
                        key: "action",
                        align: "center",
                        width: 300,
                        slot: 'action',
                        fixed: 'right'
                    }
                ],
                data: [],
                pageNumber: 1,
                pageSize: 10,
                total: 0,
                permData: [],
                editRolePermId: "",
                selectAllFlag: false,
                depData: [],
                dataType: 0,
                editDepartments: []
            };
        },
        methods: {
            init() {
                this.getRoleList();
                // 获取所有菜单权限树
                this.getPermList();
                // 获取一级部门数据
                this.getParentList();
            },
            changePage(v) {
                this.pageNumber = v;
                this.getRoleList();
                this.clearSelectAll();
            },
            changePageSize(v) {
                this.pageSize = v;
                this.getRoleList();
            },
            changeSort(e) {
                this.sortColumn = e.key;
                this.sortType = e.order;
                if (e.order === "normal") {
                    this.sortType = "";
                }
                this.getRoleList();
            },
            getRoleList() {
                this.loading = true;
                let params = {
                    pageNumber: this.pageNumber,
                    pageSize: this.pageSize,
                    sort: this.sortColumn,
                    order: this.sort
                };
                getRoleList(params).then(res => {
                    this.loading = false;
                    if (res.code === "0000") {
                        this.data = res.data.records;
                        this.total = res.data.total;
                    }
                });
            },
            getPermList() {
                this.treeLoading = true;
                getAllPermissionList().then(res => {
                    this.treeLoading = false;
                    if (res.code === "0000") {
                        this.deleteDisableNode(res.data);
                        this.permData = res.data;
                    }
                });
            },
            // 递归标记禁用节点
            deleteDisableNode(permData) {
                let that = this;
                permData.forEach(function (e) {
                    if (e.status === -1) {
                        e.title = "[已禁用] " + e.title;
                        e.disabled = true;
                    }
                    if (e.children && e.children.length > 0) {
                        that.deleteDisableNode(e.children);
                    }
                });
            },
            cancelRole() {
                this.roleModalVisible = false;
                this.$refs.roleForm.resetFields();
                this.$nextTick(()=>{
                    this.transSearchData.splice(0,this.transSearchData.length);
                    this.transData.splice(0,this.transData.length);
                    this.transInit = false;
                })
            },
            submitRole() {
                this.$refs.roleForm.validate(valid => {
                    if (valid) {
                        if (this.modalType === 0) {
                            // 添加
                            this.submitLoading = true;
                            addRole({roleName:this.roleForm.roleName,roleCode:this.roleForm.roleCode},this.transData).then(res => {
                                this.submitLoading = false;
                                if (res.code === "0000") {
                                    this.$Message.success("操作成功");
                                    this.getRoleList();
                                    this.roleModalVisible = false;
                                    this.transInit = false;
                                }
                            }).catch(()=>{
                                this.submitLoading = false;
                            });
                        } else {
                            this.submitLoading = true;
                            editRole(this.roleForm,this.transData).then(res => {
                                this.submitLoading = false;
                                if (res.code === "0000") {
                                    this.$Message.success("操作成功");
                                    this.getRoleList();
                                    this.roleModalVisible = false;
                                    this.transInit = false;
                                }
                            }).catch(()=>{
                                this.submitLoading = false;
                            });;
                        }
                    }
                });
            },
            addRole() {
                this.modalType = 0;
                this.modalTitle = "添加角色";
                this.$refs.roleForm.resetFields();
                delete this.roleForm.id;
                this.roleModalVisible = true;
                let self = this;
                userTransferList(-1).then(res=>{
                    if (res.code === "0000") {
                        self.transSearchData.splice(0,self.transSearchData.length);
                        self.transSearchData.push(...res.data.transferList);
                        self.transData.splice(0,self.transData.length);
                        self.transData.push(...res.data.keys);
                        this.transInit = true
                    }
                })
            },
            edit(v) {
                this.modalType = 1;
                this.modalTitle = "编辑角色";
                // 转换null为""
                for (let attr in v) {
                    if (v[attr] === null) {
                        v[attr] = "";
                    }
                }
                let str = JSON.stringify(v);
                let roleInfo = JSON.parse(str);
                this.roleForm = roleInfo;
                this.roleModalVisible = true;
                let self = this;
                userTransferList(v.id).then(res=>{
                    if (res.code === "0000") {
                        self.transSearchData.splice(0,self.transSearchData.length);
                        self.transSearchData.push(...res.data.transferList);
                        self.transData.splice(0,self.transData.length);
                        self.transData.push(...res.data.keys);
                        this.transInit = true
                    }
                })
            },
            remove(v) {
                this.$Modal.confirm({
                    title: "确认删除",
                    content: "您确认要删除角色 " + v.roleName + " ?",
                    onOk: () => {
                        this.operationLoading = true;
                        deleteRole(v.id).then(res => {
                            this.operationLoading = false;
                            if (res.code === "0000") {
                                this.$Message.success("删除成功");
                                this.getRoleList();
                            }
                        });
                    }
                });
            },
            clearSelectAll() {
                this.$refs.table.selectAll(false);
            },
            changeSelect(e) {
                this.selectList = e;
                this.selectCount = e.length;
            },
            delAll() {
                if (this.selectCount <= 0) {
                    this.$Message.warning("您还未选择要删除的数据");
                    return;
                }
                this.$Modal.confirm({
                    title: "确认删除",
                    content: "您确认要删除所选的 " + this.selectCount + " 条数据?",
                    onOk: () => {
                        let ids = "";
                        this.selectList.forEach(function (e) {
                            ids += e.id + ",";
                        });
                        ids = ids.substring(0, ids.length - 1);
                        this.operationLoading = true;
                        deleteRole(ids).then(res => {
                            this.operationLoading = false;
                            if (res.code === "0000") {
                                this.$Message.success("删除成功");
                                this.clearSelectAll();
                                this.getRoleList();
                            }
                        });
                    }
                });
            },
            editPerm(v) {
                this.editRolePermId = v.id;
                console.log(v)
                this.modalTitle = "分配 " + v.roleName + " 的菜单权限(点击选择)";
                // 匹配勾选
                let rolePerms = v.permissions;
                // 递归判断子节点
                this.checkPermTree(this.permData, rolePerms);
                this.permModalVisible = true;
            },
            // 递归判断子节点
            checkPermTree(permData, rolePerms) {
                let that = this;
                permData.forEach(function (p) {
                    if (that.hasPerm(p, rolePerms)) {
                        p.selected = true;
                    } else {
                        p.selected = false;
                    }
                    if (p.children && p.children.length > 0) {
                        that.checkPermTree(p.children, rolePerms);
                    }
                });
            },
            // 判断角色拥有的权限节点勾选
            hasPerm(p, rolePerms) {
                let flag = false;
                for (let i = 0; i < rolePerms.length; i++) {
                    if (p.id === rolePerms[i].permissionId) {
                        flag = true;
                        break;
                    }
                }
                if (flag) {
                    return true;
                }
                return false;
            },
            // 全选反选
            selectTreeAll() {
                this.selectAllFlag = !this.selectAllFlag;
                let select = this.selectAllFlag;
                this.selectedTreeAll(this.permData, select);
            },
            // 递归全选节点
            selectedTreeAll(permData, select) {
                let that = this;
                permData.forEach(function (e) {
                    e.selected = select;
                    if (e.children && e.children.length > 0) {
                        that.selectedTreeAll(e.children, select);
                    }
                });
            },
            submitPermEdit() {
                this.submitPermLoading = true;
                let permIds = [];
                let selectedNodes = this.$refs.tree.getSelectedNodes();
                selectedNodes.forEach(function (e) {
                    permIds.push(e.id);
                });
                editRolePerm({
                    roleId: this.editRolePermId,
                    permIds: permIds
                }).then(res => {
                    this.submitPermLoading = false;
                    if (res.code === "0000") {
                        this.$Message.success("操作成功");
                        util.initSystem(this);
                        this.getRoleList();
                        this.permModalVisible = false;
                    }
                });
            },
            cancelPermEdit() {
                this.permModalVisible = false;
            },
            getParentList() {
                this.depTreeLoading = true;
                initDepartment({openDataFilter: false}).then(res => {
                    this.depTreeLoading = false;
                    if (res.code === "0000") {
                        res.data.forEach(function (e) {
                            e.selected = false;
                            if (e.isParent) {
                                e.loading = false;
                                e.children = [];
                            }
                            if (e.status === -1) {
                                e.title = "[已禁用] " + e.title;
                                e.disabled = true;
                            }
                        });
                        this.depData = res.data;
                    }
                });
            },
            loadData(item, callback) {
                loadDepartment(item.id, {openDataFilter: false}).then(res => {
                    if (res.code === "0000") {
                        res.data.forEach(function (e) {
                            e.selected = false;
                            if (e.isParent) {
                                e.loading = false;
                                e.children = [];
                            }
                            if (e.status === -1) {
                                e.title = "[已禁用] " + e.title;
                                e.disabled = true;
                            }
                        });
                        callback(res.data);
                    }
                });
            },
            editDep(v) {
                this.dataType = 0;
                console.log(v)
                this.editRolePermId = v.id;
                this.modalTitle = "分配 " + v.roleName + " 的数据权限";
                if (v.dsType) {
                    this.dataType = parseInt(v.dsType);
                }
                // 匹配勾选
                let roleDepIds = v.departments;
                this.editDepartments = roleDepIds;
                // 判断子节点
                this.checkDepTree(this.depData, roleDepIds);
                this.depModalVisible = true;
            },
            expandCheckDep(v) {
                // 判断展开子节点
                this.checkDepTree(v.children, this.editDepartments);
            },
            // 判断子节点
            checkDepTree(depData, roleDepIds) {
                let that = this;
                depData.forEach(function (p) {
                    if (that.hasDepPerm(p, roleDepIds)) {
                        p.selected = true;
                    } else {
                        p.selected = false;
                    }
                });
            },
            // 判断角色拥有的权限节点勾选
            hasDepPerm(p, roleDepIds) {
                let flag = false;
                for (let i = 0; i < roleDepIds.length; i++) {
                    if (p.id === roleDepIds[i]) {
                        flag = true;
                        break;
                    }
                }
                if (flag) {
                    return true;
                }
                return false;
            },
            submitDepEdit() {
                let depIds = [];
                if (this.dataType != 0) {
                    let selectedNodes = this.$refs.depTree.getSelectedNodes();
                    if (selectedNodes.length < 1) {
                        this.$Message.error("请至少选择一条数据");
                        return;
                    }
                    selectedNodes.forEach(function (e) {
                        depIds.push(e.id);
                    });
                }
                this.submitDepLoading = true;
                editRoleDep({
                    roleId: this.editRolePermId,
                    dataType: this.dataType,
                    depIds: depIds
                }).then(res => {
                    this.submitDepLoading = false;
                    if (res.code === "0000") {
                        this.$Message.success("操作成功");
                        this.getRoleList();
                        this.depModalVisible = false;
                    }
                });
            },
            userTrans(selectUsers){
                this.transData.splice(0,this.transData.length);
                this.transData.push(...selectUsers);
            }
        },
        mounted() {
            this.init();
        }
    };
</script>
